package com.ncmmall.application.business.merchant;

import com.ncmmall.application.msm.AliYunSmsService;
import com.feijin.commons.lang.PropertiesHelps;
import com.feijin.commons.lang.Randoms;
import com.feijin.commons.lang.Requires;
import com.feijin.commons.securitys.MD5HashUtils;
import com.ncmmall.domain.business.goods.channel.GoodsChannel;
import com.ncmmall.domain.business.goods.channel.QGoodsChannel;
import com.ncmmall.domain.business.merchant.MerchantEnterpriseInfo;
import com.ncmmall.domain.business.merchant.MerchantEnterpriseInfoRepository;
import com.ncmmall.domain.business.merchant.MerchantGoodsChannel;
import com.ncmmall.domain.business.merchant.MerchantGoodsChannelRepository;
import com.ncmmall.domain.business.merchant.MerchantIndividualInfo;
import com.ncmmall.domain.business.merchant.MerchantIndividualInfoRepository;
import com.ncmmall.domain.business.merchant.MerchantPersonalInfo;
import com.ncmmall.domain.business.merchant.MerchantPersonalInfoRepository;
import com.ncmmall.domain.business.merchant.QMerchantGoodsChannel;
import com.ncmmall.domain.security.role.QRole;
import com.ncmmall.domain.security.role.Role;
import com.ncmmall.domain.security.user.QWebUser;
import com.ncmmall.domain.security.user.WebUser;
import com.ncmmall.domain.security.user.WebUserRepository;
import com.ncmmall.querychannel.service.QueryChannelService;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @author linxs
 * 商家管理
 */
@Service
@Transactional
@Slf4j
public class MerchantApplication {

    @Autowired
    private WebUserRepository merchantRepository;

    @Autowired
    private MerchantEnterpriseInfoRepository enterpriseInfoRepository;

    @Autowired
    private MerchantIndividualInfoRepository individualInfoRepository;

    @Autowired
    private MerchantPersonalInfoRepository personalInfoRepository;

    @Autowired
    private MerchantGoodsChannelRepository merchantGoodsChannelRepository;

    @Autowired
    private QueryChannelService queryChannelService;

    /**
     * /**
     * 禁用账号
     */
    public void disable(WebUser user) {
        user.setAccountNonLocked(false);
        merchantRepository.save(user);
    }

    /**
     * 启用账号
     */
    public void enabled(WebUser user) {
        user.setAccountNonLocked(true);
        merchantRepository.save(user);
    }

    private void checkMerchantBaseInfo(WebUser merchant) {

        Requires.hasLength(merchant.getBankAccountHolder(), "开户人不能为空");
        Requires.hasLength(merchant.getBankCardNo(), "银行卡号不能为空");
        Requires.hasLength(merchant.getBankName(), "开户行不能为空");
        Requires.hasLength(merchant.getBankMobile(), "预留手机号不能为空");
        Requires.hasLength(merchant.getBankProvince(), "所属省不能为空");
        Requires.hasLength(merchant.getBankCity(), "所属市不能为空");
        Requires.hasLength(merchant.getMerchantGoodsChannelsData(), "经营商品类目不能为空");
        Requires.hasLength(merchant.getShopName(), "店铺名称不能为空");
        Requires.hasLength(merchant.getRealName(), "真实姓名不能为空");
        Requires.isTrue(merchant.getMainType() > 0 && merchant.getMainType() <= 3, "商家主体类型不能为空");

        String email = merchant.getEmail();
        String mobile = merchant.getMobile();

        Requires.hasLength(email, "邮箱不能为空");
        Requires.hasLength(mobile, "手机号码不能为空");


        List<WebUser> users;

        if (merchant.getId() <= 0) {

            String username = merchant.getUsername();
            String password = merchant.getPassword();

            Requires.hasLength(username, "账号不能为空");
            Requires.hasLength(password, "密码不能为空");

            users = queryChannelService.findAll(QWebUser.webUser.role.name.eq("MERCHANT").and(QWebUser.webUser.username.eq(username)), WebUser.class);
            Requires.isTrue(users.size() == 0, "用户名已存在");

            users = queryChannelService.findAll(QWebUser.webUser.role.name.eq("MERCHANT").and(QWebUser.webUser.email.eq(email)), WebUser.class);
            Requires.isTrue(users.size() == 0, "邮箱已存在");

            users = queryChannelService.findAll(QWebUser.webUser.role.name.eq("MERCHANT").and(QWebUser.webUser.mobile.eq(mobile)), WebUser.class);
            Requires.isTrue(users.size() == 0, "手机号码已存在");

        } else {

            users = queryChannelService.findAll(QWebUser.webUser.role.name.eq("MERCHANT").and(QWebUser.webUser.email.eq(email)).and(QWebUser.webUser.id.ne(merchant.getId())), WebUser.class);
            Requires.isTrue(users.size() == 0, "邮箱已存在");

            users = queryChannelService.findAll(QWebUser.webUser.role.name.eq("MERCHANT").and(QWebUser.webUser.mobile.eq(mobile)).and(QWebUser.webUser.id.ne(merchant.getId())), WebUser.class);
            Requires.isTrue(users.size() == 0, "手机号码已存在");

        }


    }

    private void checkEnterpriseMerchant(MerchantEnterpriseInfo enterpriseInfo) {
        Requires.hasLength(enterpriseInfo.getCompany(), "公司名称不能为空");
        Requires.hasLength(enterpriseInfo.getLegalPersonRealname(), "法人姓名不能为空");
        Requires.hasLength(enterpriseInfo.getLegalPersonIdCardNo(), "法人身份证不能为空");
        Requires.hasLength(enterpriseInfo.getProvince(), "区域省不能为空");
        Requires.hasLength(enterpriseInfo.getCity(), "区域市不能为空");
        Requires.hasLength(enterpriseInfo.getArea(), "区域县不能为空");
        Requires.hasLength(enterpriseInfo.getLegalPersonIdCardPhoto(), "法人身份证正面不能为空");
        Requires.hasLength(enterpriseInfo.getLegalPersonIdCardPhotoBack(), "法人身份证反面不能为空");
        Requires.hasLength(enterpriseInfo.getBusinessLicensePhoto(), "公司营业执照不能为空");
        Requires.hasLength(enterpriseInfo.getBusinessLicenseNo(), "营业执照号码不能为空");
        Requires.hasLength(enterpriseInfo.getAddress(), "地址不能为空");
    }

    private void checkIndividualMerchant(MerchantIndividualInfo individualHouseholdInfo) {
        Requires.hasLength(individualHouseholdInfo.getLegalPersonRealname(), "姓名不能为空");
        Requires.hasLength(individualHouseholdInfo.getProvince(), "区域省不能为空");
        Requires.hasLength(individualHouseholdInfo.getCity(), "区域市不能为空");
        Requires.hasLength(individualHouseholdInfo.getArea(), "区域县不能为空");
        Requires.hasLength(individualHouseholdInfo.getIdCardNo(), "身份证号码不能为空");
        Requires.hasLength(individualHouseholdInfo.getIdCardPhoto(), "身份证正面不能为空");
        Requires.hasLength(individualHouseholdInfo.getIdCardPhotoBack(), "身份证反面不能为空");
        Requires.hasLength(individualHouseholdInfo.getBusinessLicensePhoto(), "营业执照不能为空");
        Requires.hasLength(individualHouseholdInfo.getBusinessLicenseNo(), "营业执照号码不能为空");
        Requires.hasLength(individualHouseholdInfo.getAddress(), "地址不能为空");
    }

    private void checkPersonalMerchant(MerchantPersonalInfo personalInfo) {
        Requires.hasLength(personalInfo.getLegalPersonRealname(), "姓名不能为空");
        Requires.hasLength(personalInfo.getProvince(), "区域省不能为空");
        Requires.hasLength(personalInfo.getCity(), "区域市不能为空");
        Requires.hasLength(personalInfo.getArea(), "区域县不能为空");
        Requires.hasLength(personalInfo.getIdCardNo(), "身份证号码不能为空");
        Requires.hasLength(personalInfo.getLegalPersonIdCardPhoto(), "身份证正面不能为空");
        Requires.hasLength(personalInfo.getLegalPersonIdCardPhotoBack(), "身份证反面不能为空");
    }


    /**
     * 添加商家
     */
    public WebUser createMerchant(WebUser merchant) {

        checkMerchantBaseInfo(merchant);

        if (merchant.isEnterpriseMerchant()) {
            MerchantEnterpriseInfo enterpriseInfo = merchant.getMerchantEnterpriseInfo();
            checkEnterpriseMerchant(enterpriseInfo);

            enterpriseInfoRepository.save(enterpriseInfo);
            merchant.setMerchantEnterpriseInfo(enterpriseInfo);
            merchant.setMerchantIndividualInfo(null);
            merchant.setMerchantPersonalInfo(null);
        }

        if (merchant.isIndividualMerchant()) {
            MerchantIndividualInfo individualHouseholdInfo = merchant.getMerchantIndividualInfo();
            checkIndividualMerchant(individualHouseholdInfo);

            individualInfoRepository.save(individualHouseholdInfo);
            merchant.setMerchantIndividualInfo(individualHouseholdInfo);
            merchant.setMerchantEnterpriseInfo(null);
            merchant.setMerchantPersonalInfo(null);
        }

        if (merchant.isPersonalMerchant()) {
            MerchantPersonalInfo personalInfo = merchant.getMerchantPersonalInfo();
            checkPersonalMerchant(personalInfo);

            personalInfoRepository.save(personalInfo);
            merchant.setMerchantPersonalInfo(personalInfo);
            merchant.setMerchantEnterpriseInfo(null);
            merchant.setMerchantIndividualInfo(null);
        }

        String userNo = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + Randoms.generateDigitalString(5);
        merchant.setUserNo(userNo);
        merchant.setRole(queryChannelService.findOne(QRole.role.name.eq("MERCHANT"), Role.class));
        String passwordAsMd5 = MD5HashUtils.asMD5(MD5HashUtils.MD5(merchant.getPassword()), merchant.getUsername());
        merchant.setPassword(passwordAsMd5);
        merchant.setAccountNonLocked(true);
        merchant.setAccessToken(MD5HashUtils.md5(passwordAsMd5, merchant.getUsername()));
        merchant.setCreateTime(new Timestamp(System.currentTimeMillis()));
        merchant.setMerchantEnterTime(merchant.getCreateTime());
        merchant.setAccountNonLocked(false);
        merchant.setMerchantCheckStatus(1);

        merchantRepository.save(merchant);

        List<String> merchantGoodsChannelIds = Splitter.on("-").omitEmptyStrings().trimResults().splitToList(merchant.getMerchantGoodsChannelsData());
        for (String item : merchantGoodsChannelIds) {
            MerchantGoodsChannel goodsChannel = new MerchantGoodsChannel();
            goodsChannel.setChannel(queryChannelService.findOne(QGoodsChannel.goodsChannel.id.eq(Long.parseLong(item)), GoodsChannel.class));
            goodsChannel.setMerchant(merchant);
            merchantGoodsChannelRepository.save(goodsChannel);
        }

        return merchant;

    }

    /**
     * 添加供应商
     */
    public void createSupplier(WebUser merchant) {

        if (merchant.isEnterpriseMerchant()) {
            MerchantEnterpriseInfo enterpriseInfo = merchant.getMerchantEnterpriseInfo();
            enterpriseInfoRepository.save(enterpriseInfo);
            merchant.setMerchantEnterpriseInfo(enterpriseInfo);
            merchant.setMerchantIndividualInfo(null);
            merchant.setMerchantPersonalInfo(null);
        }

        if (merchant.isIndividualMerchant()) {
            MerchantIndividualInfo individualHouseholdInfo = merchant.getMerchantIndividualInfo();
            individualInfoRepository.save(individualHouseholdInfo);
            merchant.setMerchantIndividualInfo(individualHouseholdInfo);
            merchant.setMerchantEnterpriseInfo(null);
            merchant.setMerchantPersonalInfo(null);
        }

        if (merchant.isPersonalMerchant()) {
            MerchantPersonalInfo personalInfo = merchant.getMerchantPersonalInfo();
            personalInfoRepository.save(personalInfo);
            merchant.setMerchantPersonalInfo(personalInfo);
            merchant.setMerchantEnterpriseInfo(null);
            merchant.setMerchantIndividualInfo(null);
        }

        String userNo = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + Randoms.generateDigitalString(5);
        merchant.setUserNo(userNo);
        merchant.setRole(queryChannelService.findOne(QRole.role.name.eq("SUPPLIER"), Role.class));
        String passwordAsMd5 = MD5HashUtils.asMD5(MD5HashUtils.MD5(merchant.getPassword()), merchant.getUsername());
        merchant.setPassword(passwordAsMd5);
        merchant.setAccountNonLocked(true);
        merchant.setAccessToken(MD5HashUtils.md5(passwordAsMd5, merchant.getUsername()));
        merchant.setCreateTime(new Timestamp(System.currentTimeMillis()));
        merchant.setMerchantEnterTime(merchant.getCreateTime());
        merchant.setAccountNonLocked(false);
        merchant.setMerchantCheckStatus(1);
        merchant.setSelfSupport(1);
        merchantRepository.save(merchant);

        List<String> merchantGoodsChannelIds = Splitter.on("-").omitEmptyStrings().trimResults().splitToList(merchant.getMerchantGoodsChannelsData());
        for (String item : merchantGoodsChannelIds) {
            MerchantGoodsChannel goodsChannel = new MerchantGoodsChannel();
            goodsChannel.setChannel(queryChannelService.findOne(QGoodsChannel.goodsChannel.id.eq(Long.parseLong(item)), GoodsChannel.class));
            goodsChannel.setMerchant(merchant);
            merchantGoodsChannelRepository.save(goodsChannel);
        }

    }

    /**
     * 批量启用
     */
    public void enables(List<WebUser> merchants) {
        for (WebUser merchant : merchants) {
            enabled(merchant);
        }
    }

    /**
     * 批量禁用
     */
    public void disables(List<WebUser> merchants) {
        for (WebUser merchant : merchants) {
            disable(merchant);
        }
    }

    /**
     * 编辑商家信息
     */
    public void modifyMerchant(WebUser params) {

        checkMerchantBaseInfo(params);
        WebUser merchant = queryChannelService.findOne(QWebUser.webUser.id.eq(params.getId()), WebUser.class);

        if (merchant.isEnterpriseMerchant()) {
            MerchantEnterpriseInfo enterpriseInfo = params.getMerchantEnterpriseInfo();
            checkEnterpriseMerchant(enterpriseInfo);

            enterpriseInfoRepository.save(enterpriseInfo);
            merchant.setMerchantEnterpriseInfo(enterpriseInfo);
            merchant.setMerchantIndividualInfo(null);
            merchant.setMerchantPersonalInfo(null);
        }

        if (merchant.isIndividualMerchant()) {
            MerchantIndividualInfo individualHouseholdInfo = params.getMerchantIndividualInfo();
            checkIndividualMerchant(individualHouseholdInfo);

            individualInfoRepository.save(individualHouseholdInfo);
            merchant.setMerchantIndividualInfo(individualHouseholdInfo);
            merchant.setMerchantEnterpriseInfo(null);
            merchant.setMerchantPersonalInfo(null);
        }

        if (merchant.isPersonalMerchant()) {
            MerchantPersonalInfo personalInfo = params.getMerchantPersonalInfo();
            checkPersonalMerchant(personalInfo);

            personalInfoRepository.save(personalInfo);
            merchant.setMerchantPersonalInfo(personalInfo);
            merchant.setMerchantEnterpriseInfo(null);
            merchant.setMerchantIndividualInfo(null);
        }

        merchant.setShopName(params.getShopName());
        merchant.setRealName(params.getRealName());
        merchant.setEmail(params.getEmail());
        merchant.setMobile(params.getMobile());
        merchant.setWechat(params.getWechat());
        merchant.setQq(params.getQq());
        merchant.setMainType(params.getMainType());

        merchant.setBankName(params.getBankName());
        merchant.setBankCardNo(params.getBankCardNo());
        merchant.setBankAccountHolder(params.getBankAccountHolder());
        merchant.setBankCity(params.getBankCity());
        merchant.setBankProvince(params.getBankProvince());
        merchant.setBankMobile(params.getBankMobile());
        merchant.setBankSubBranchName(params.getBankSubBranchName());
        merchant.setAvatar(params.getAvatar());
        merchant.setCertificate(params.getCertificate());

        merchantRepository.save(merchant);

        List<MerchantGoodsChannel> channels = queryChannelService.findAll(QMerchantGoodsChannel.merchantGoodsChannel.merchant.id.eq(params.getId()), MerchantGoodsChannel.class);
        merchantGoodsChannelRepository.delete(channels);

        List<String> merchantGoodsChannelIds = Splitter.on("-").omitEmptyStrings().trimResults().splitToList(params.getMerchantGoodsChannelsData());
        for (String item : merchantGoodsChannelIds) {
            MerchantGoodsChannel goodsChannel = new MerchantGoodsChannel();
            goodsChannel.setChannel(queryChannelService.findOne(QGoodsChannel.goodsChannel.id.eq(Long.parseLong(item)), GoodsChannel.class));
            goodsChannel.setMerchant(merchant);
            merchantGoodsChannelRepository.save(goodsChannel);
        }
    }

    /**
     * 审核商家
     */
    public void checkMerchant(WebUser params) {
        WebUser merchant = queryChannelService.findOne(QWebUser.webUser.id.eq(params.getId()), WebUser.class);
        merchant.setMerchantCheckStatus(params.getMerchantCheckStatus());
        merchant.setMerchantCheckNote(params.getMerchantCheckNote());
        merchantRepository.save(merchant);

        if (merchant.getMerchantCheckStatus() == 2) {
            AliYunSmsService.send(merchant.getMobile(),
                    PropertiesHelps.getValue("sign_name"),
                    "SMS_211020827",
                    ImmutableMap.of("password", "123456"));
        }

        if (merchant.getMerchantCheckStatus() == 3) {
            AliYunSmsService.send(merchant.getMobile(),
                    PropertiesHelps.getValue("sign_name"),
                    "SMS_211025768", null);
        }


    }

    /**
     * 设置自提地址
     */
    public void setterShippingAddress(WebUser merchant, String address) {
        merchant.setWarehouseAddress(address);
        merchantRepository.save(merchant);
    }

    /**
     * 设为自营
     */
    public void selfSupport(WebUser merchant) {
        merchant.setSelfSupport(1);
        merchantRepository.save(merchant);
    }

    /**
     * 取消自营
     */
    public void cancelSelfSupport(WebUser merchant) {
        merchant.setSelfSupport(0);
        merchantRepository.save(merchant);
    }

    public WebUser modifyMerchantInfo(WebUser params) {
        WebUser merchant = queryChannelService.findOne(QWebUser.webUser.id.eq(params.getId()), WebUser.class);

        if (params.isEnterpriseMerchant()) {
            MerchantEnterpriseInfo enterpriseInfo = params.getMerchantEnterpriseInfo();
            enterpriseInfoRepository.save(enterpriseInfo);
            merchant.setMerchantEnterpriseInfo(enterpriseInfo);
            merchant.setMerchantIndividualInfo(null);
            merchant.setMerchantPersonalInfo(null);
        }

        if (params.isIndividualMerchant()) {
            MerchantIndividualInfo individualHouseholdInfo = params.getMerchantIndividualInfo();
            individualInfoRepository.save(individualHouseholdInfo);
            merchant.setMerchantIndividualInfo(individualHouseholdInfo);
            merchant.setMerchantEnterpriseInfo(null);
            merchant.setMerchantPersonalInfo(null);
        }

        if (params.isPersonalMerchant()) {
            MerchantPersonalInfo personalInfo = params.getMerchantPersonalInfo();
            personalInfoRepository.save(personalInfo);
            merchant.setMerchantPersonalInfo(personalInfo);
            merchant.setMerchantEnterpriseInfo(null);
            merchant.setMerchantIndividualInfo(null);
        }

        merchant.setShopName(params.getShopName());
        merchant.setRealName(params.getRealName());
        merchant.setEmail(params.getEmail());
        merchant.setMobile(params.getMobile());
        merchant.setWechat(params.getWechat());
        merchant.setQq(params.getQq());
        merchant.setMainType(params.getMainType());
        merchant.setShopBanner(params.getShopBanner());

        merchant.setAvatar(params.getAvatar());
        merchant.setCertificate(params.getCertificate());

        merchant.setBankName(params.getBankName());
        merchant.setBankCardNo(params.getBankCardNo());
        merchant.setBankAccountHolder(params.getBankAccountHolder());
        merchant.setBankCity(params.getBankCity());
        merchant.setBankProvince(params.getBankProvince());
        merchant.setBankMobile(params.getBankMobile());
        merchant.setBankSubBranchName(params.getBankSubBranchName());

        merchantRepository.save(merchant);

        return merchant;
    }

    /**
     * 重置密码
     */
    public void modifyPassword(WebUser merchant, String password) {
        String passwordAsMd5 = MD5HashUtils.asMD5(password, merchant.getUsername());
        merchant.setPassword(passwordAsMd5);
        merchantRepository.save(merchant);
    }
}
